#include <Windows.h>
#include <CommDlg.h>
#include <extend.h>

typedef struct
{
    WORD vlen;
    BYTE data[10];
} ESCDATA;

static far PRINTDLG pd;
static far BOOL bInit = FALSE;

//----------------------------------------------------------------------------//

static void PrinterInit( void )
{
   if( ! bInit )
   {
      bInit = TRUE;
      _bset( ( BYTE * ) &pd, 0, sizeof( PRINTDLG ) );
      pd.lStructSize = sizeof( PRINTDLG );
      pd.hwndOwner   = GetActiveWindow();
      pd.Flags       = PD_RETURNDEFAULT ;
      PrintDlg( &pd );
   }
}

//----------------------------------------------------------------------------//

CLIPPER PRINTERINI() //T
{
   bInit = FALSE;
}

//----------------------------------------------------------------------------//

CLIPPER GetPrintDC() // ( hWndOwner ) --> hDC
{
   PrinterInit();

   pd.hwndOwner = ( HWND ) _parnl( 1 );
   pd.Flags     = PD_RETURNDC | PD_USEDEVMODECOPIES |
                  PD_HIDEPRINTTOFILE | PD_NOSELECTION ;

   _retnl( ( LONG ) ( PrintDlg( &pd ) ? pd.hDC: 0 ) );
}

//----------------------------------------------------------------------------//

CLIPPER PRINTERSET() // up( hWndOwner ) --> nil
{
   PrinterInit();

   pd.hwndOwner = IF( PCOUNT() == 0, GetActiveWindow(), ( HWND ) _parnl( 1 ) );
   pd.Flags     = PD_PRINTSETUP | PD_USEDEVMODECOPIES;

   PrintDlg( &pd );
}

//----------------------------------------------------------------------------//

CLIPPER StartDOC()
{
   DOCINFO info;

   if( _parclen( 2 ) > 31 )
      _parc( 2 )[ 31 ] = 0;             // cannot exceed 32 chars

   info.cbSize      = sizeof( DOCINFO );
   info.lpszDocName = IF( ISCHAR( 2 ), _parc( 2 ), "" );
   info.lpszOutput  = IF( ISCHAR( 3 ), _parc( 3 ), 0 );

   _retni( StartDoc( ( HDC ) _parnl( 1 ),       // hDC printer device
                     &info ) );
}

//----------------------------------------------------------------------------//

CLIPPER EndDOC()
{
   _retni( EndDoc( ( HDC ) _parnl( 1 ) ) );     // hDC printer device
}

//----------------------------------------------------------------------------//

CLIPPER StartPAGE()
{
   _retni( StartPage( ( HDC ) _parnl( 1 ) ) );  // hDC printer device
}

//----------------------------------------------------------------------------//

CLIPPER EndPAGE()
{
   _retni( EndPage( ( HDC ) _parnl( 1 ) ) );    // hDC printer device
}

//----------------------------------------------------------------------------//

CLIPPER ESCAPE() // ( hDC, nEscape, cInput, @cOutPut ) --> nReturn
{
   POVM pOVM      = IF( PCOUNT() == 4, _vmAlloc( _parclen( 3 ) ), 0 );
   BYTE * pBuffer = IF( PCOUNT() == 4, _vmLock( pOVM ), 0 );

   _retni( Escape( ( HDC ) _parnl( 1 ), _parni( 2 ), _parclen( 3 ), _parc( 3 ),
                   pBuffer ) );

   if( pBuffer )
   {
      _storclen( pBuffer, _parclen( 3 ), 4 );
      _vmFree( pOVM );
   }
}

//----------------------------------------------------------------------------//

CLIPPER GETPRINTDE() // FAULT( hWndOwner ) --> nil
{
   LPDEVNAMES lpDevNames;
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );
   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   _retnl( ( LONG ) CreateDC( ( LPSTR ) lpDevNames + lpDevNames->wDriverOffset,
                     ( LPSTR ) lpDevNames + lpDevNames->wDeviceOffset,
                     ( LPSTR ) lpDevNames + lpDevNames->wOutputOffset,
                     lpDevMode ) );

   GlobalUnlock( pd.hDevNames );
   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

CLIPPER PRNOFFSET() // ( hDC)  --> aPoint
{
   POINT pt;

   pt.y = 0;
   pt.x = 0;

   Escape( ( HDC ) _parnl( 1 ),
           GETPRINTINGOFFSET,
           NULL, NULL, ( LPPOINT ) &pt ) ;

   _reta( 2 );
   _storni( pt.y, -1, 2 );
   _storni( pt.x, -1, 1 );
}

//----------------------------------------------------------------------------//

CLIPPER RESETDC() // hDC --> lSuccess
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode = ( LPDEVMODE ) GlobalLock( pd.hDevMode );

   _retl( ( BOOL ) ResetDC( ( HDC ) _parnl( 1 ), lpDevMode ) );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

CLIPPER PRNGETSIZE() // ( hDC)  --> aPoint
{
   POINT pt;

   pt.y = 0;
   pt.x = 0;

   Escape( ( HDC ) _parnl( 1 ),
           GETPHYSPAGESIZE,
           NULL, NULL, ( LPPOINT ) &pt ) ;

   _reta( 2 );
   _storni( pt.y, -1, 2 );
   _storni( pt.x, -1, 1 );
}

//----------------------------------------------------------------------------//

CLIPPER PRNLANDSCA() // PE(hDC)  --> lSuccess
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmOrientation = DMORIENT_LANDSCAPE;

   GlobalUnlock( pd.hDevMode );

   _retl( TRUE );

}

//----------------------------------------------------------------------------//

CLIPPER PRNSETSIZE()
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmFields      = lpDevMode->dmFields | DM_PAPERSIZE |
                              DM_PAPERLENGTH | DM_PAPERWIDTH;
   lpDevMode->dmPaperSize   = DMPAPER_USER;
   lpDevMode->dmPaperWidth  = _parnl( 1 );
   lpDevMode->dmPaperLength = _parnl( 2 );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

CLIPPER PRNPORTRAI() // T()  --> lSuccess
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmOrientation = DMORIENT_PORTRAIT;

   GlobalUnlock( pd.hDevMode );

   _retl( TRUE );
}

//----------------------------------------------------------------------------//

CLIPPER PRNGETORIE() // NTATION()  --> nOldOrient
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   _retni( lpDevMode->dmOrientation );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

CLIPPER PRNSETCOPI() // ES( nCopies )  --> lSuccess
{
   LPDEVMODE lpDevMode;

   PrinterInit();

   lpDevMode = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmCopies = _parni( 1 );

   if( PCOUNT() == 2 )  // Compatibility with previous syntax!
      lpDevMode->dmCopies = _parni( 2 );

   GlobalUnlock( pd.hDevMode );

   _retl( TRUE );
}

//----------------------------------------------------------------------------//

CLIPPER PRINTERESC() // ( hDC, cText ) --> lSuccess
{
   // ESCDATA Data;

   // Data.vlen = _parclen(2);

   // _bcopy( Data.data, _parc(2), _parclen(2) );

   _retni( Escape( ( HDC ) _parnl( 1 ), PASSTHROUGH, NULL, (LPSTR) _parc( 2 ), NULL ) );
}

//----------------------------------------------------------------------------//

CLIPPER PRNGETNAME() // () --> cPrinter
{
   LPDEVNAMES lpDevNames;

   PrinterInit();

   lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );

   _retc( ( LPSTR ) lpDevNames + lpDevNames->wDeviceOffset );

   GlobalUnlock( pd.hDevNames );
}

//----------------------------------------------------------------------------//

CLIPPER PRNGETPORT() // () --> cPort
{
   LPDEVNAMES lpDevNames;

   PrinterInit();

   lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );

   _retc( ( LPSTR ) lpDevNames + lpDevNames->wOutputOffset );

   GlobalUnlock( pd.hDevNames );
}

//----------------------------------------------------------------------------//

CLIPPER PRNGETDRIV() // ER () --> cDriver
{
   LPDEVNAMES lpDevNames;

   PrinterInit();

   lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );

   _retc( ( LPSTR ) lpDevNames + lpDevNames->wDriverOffset );

   GlobalUnlock( pd.hDevNames );
}
//----------------------------------------------------------------------------//

CLIPPER PRNSETPAGE()
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmPaperSize  = _parni( 1 );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

CLIPPER DraftMode() // lMode
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmFields        = lpDevMode->dmFields | DM_PRINTQUALITY;
   lpDevMode->dmPrintQuality  = IF( _parl( 1 ), -1, -4 );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

// CLIPPER SPOOLFILE()
// {
//   _retni( SpoolFile( _parc( 1 ), _parc( 2 ), _parc( 3 ), _parc( 4 ) ) );
// }

//----------------------------------------------------------------------------//
